/**
 * OSS is a Open Service Container which gives the leverage of building the Desktop and Web
 * Application. * Copyright (C) 2008-2009  Ponraj Sutanthiramani
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Or5e Open Source Community
 * 105, S.S Paradise Apartment, Munnireddy Layout, Horamavu, Banaswadi, Bangalore, India.
 */
package org.or5e.api.webcam.video;

import java.awt.*;
import org.or5e.api.webcam.images.Array2dComponent;
import org.or5e.api.webcam.util.CloseableFrame;
import org.or5e.api.webcam.util.ElapsedTimer;
import org.or5e.api.webcam.util.StatisticalSummary;

/**
 * Created by IntelliJ IDEA.
 * User: sml
 * Date: 07-Oct-2003
 * Time: 10:58:07
 * To change this template use Options | File Templates.
 */

public class FrameDifference implements ShortFrameProcessor {

    final static int RED_MASK = 0x00007F00;
    final static int RED_SHIFT = 7;     // 7 right
    final static int GREEN_MASK = 0x000003E0;
    final static int GREEN_SHIFT = 2;   // 2 right
    final static int BLUE_MASK = 0x0000001F;
    final static int BLUE_SHIFT = 3;    // 3 left
    final static int ALPHA_MASK = 0xFF000000;
    final static int MID_GREY = 128;

    int width, height;
    Array2dComponent a;
    int[] pixels;
    int[] buf;
    TextField text;
    int count;
    ElapsedTimer t;
    StatisticalSummary ss;

    @Override
    public void init(int width, int height) {
        this.width = width;
        this.height = height;
        pixels = new int[width * height];
        buf = new int[width * height];
        a = new Array2dComponent(pixels, width, height, 1);
        Panel p = new Panel();
        p.setLayout(new BorderLayout());
        text = new TextField();
        p.add(a, BorderLayout.CENTER);
        p.add(text, BorderLayout.SOUTH);
        new CloseableFrame(p, "Difference frame", true);
        t = new ElapsedTimer();
        ss = new StatisticalSummary();
    }

    @Override
    public void process(byte[] frame) {
        // reset the timer
        t.reset();
        for (int i = 0; i < Math.min(frame.length, pixels.length); i++) {
            // red, green and blue
            int r = ( (int) frame[i]) & RED_MASK ;
            r >>= RED_SHIFT;

            int g = ( (int) frame[i]) & GREEN_MASK ;
            g = g >> GREEN_SHIFT;

            int b = ( (int) frame[i]) & BLUE_MASK ;
            b = b << BLUE_SHIFT;

            // grey level - average of r, g and b
            int x = (r + g + b) / 3;
            int diff = x - buf[i];
            int p = (diff / 2) + MID_GREY;
            // set image pixel to difference in grey levels
            pixels[i] = ALPHA_MASK + p + (p << 8) + (p << 16);
            // set buffer pixel to current grey level
            buf[i] = x;
        }
        // update the difference image and repaint it
        // costs about 30ms - comment this out if not needed
        a.setPixels(pixels);
        a.repaint();
        // compute some timing statistics
        ss.add( t.elapsed() );
        text.setText( "Set: " + count++ + " frames : " + (int) ss.mean() );
    }

}
